package com.srcgeneratora.utils;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.processing.ProcessingEnvironment;
import javax.tools.Diagnostic;
import javax.tools.FileObject;
import javax.tools.JavaFileObject;
import javax.tools.StandardLocation;
import org.apache.velocity.Template;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.context.Context;

/**
 *
 * @author Camilo Alvarez camilo.alvarez at oarsoft.com>
 */
public class FileGeneratorUtil {

    private HashMap<String, Template> templateCache;
    private ProcessingEnvironment processingEnv;
    private String defaultPackage;
    private VelocityEngine ve;
    private boolean cache = true;

    public FileGeneratorUtil(ProcessingEnvironment processingEnv, String defaultPackage) {
        this.processingEnv = processingEnv;
        Properties p = new java.util.Properties();
        p.setProperty("runtime.log.logsystem.class", "org.apache.velocity.runtime.log.NullLogSystem");
        //p.setProperty("file.resource.loader.path", "/Users/cadorca/NetBeansProjects/jpa-provider/src/jpaimplgen/model/templates");
        p.put("runtime.log.invalid.references", "false");
        p.put("resource.loader", "class");
        p.put("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
        ve = new VelocityEngine();
        ve.init(p);
        templateCache = new HashMap<String, Template>();
        this.defaultPackage = defaultPackage;
    }

    public void createFile(String fileName, String templateName, Context context) {
        Template template = templateCache.get(fileName);
        if (template == null) {
            template = ve.getTemplate(defaultPackage + templateName);
            templateCache.put(fileName, template);
        }
        createFile(fileName, template, context);
    }

    public void createFile(String fileName, Template template, Context context) {
        JavaFileObject f = null;
        try {
            f = processingEnv.getFiler().createSourceFile(fileName, processingEnv.getElementUtils().getTypeElement("com.oarsoft.sas.persistence.entity.Areas"));
        } catch (IOException ex) {
            Logger.getLogger(FileGeneratorUtil.class.getName()).log(Level.SEVERE, null, ex);
        }
        mergeTeplate(f, template, context);
    }

    public void createResourceFile(String fileName, String templateName, Context context) {
        FileObject f = null;
        try {
            f = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", fileName);
        } catch (IOException ex) {
            Logger.getLogger(FileGeneratorUtil.class.getName()).log(Level.SEVERE, null, ex);
        }
        Template template = templateCache.get(fileName);
        if (template == null) {
            template = ve.getTemplate(defaultPackage + templateName);
            templateCache.put(fileName, template);
        }
        mergeTeplate(f, template, context);

    }

    private void mergeTeplate(FileObject f, Template template, Context context) {
        PrintWriter pw = null;
        Writer w = null;
        try {
            processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Creating " + f.toUri());
            w = f.openWriter();
            pw = new PrintWriter(w);
            template.merge(context, pw);
        } catch (Exception exception) {
            exception.printStackTrace();
        } finally {
            pw.flush();
            try {
                w.close();
            } catch (IOException ex) {
                Logger.getLogger(FileGeneratorUtil.class.getName()).log(Level.SEVERE, null, ex);
            }
            pw.close();
        }
    }
}
